/* 
 * Enterprise Library Extensions - DI + ORM.
 * Copyright (C) 2006
 *
 * GNU General Public License
 *
 * This program is free software; you can redistribute 
 * it and/or modify it under the terms of the GNU General Public License 
 * as published by the Free Software Foundation; either version 2 of the 
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but 
 * WITHOUT ANY WARRANTY; without even the implied warranty of 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
 * See the GNU General Public License for more details.
 */
using System;
using System.Collections.Generic;
using System.Text;

namespace ELE.EnterpriseLibrary.Data
{
  /// <summary>
  /// Defines a property binding in an object mapping.
  /// <para>Multiple instances of this class live under <see cref="ObjectSqlMappingTable"/></para>
  /// </summary>
  public class ObjectPropertySqlBinding : NamedItem, ICloneable
  {
    private string tableName;
    private string propertyName;
    private string inputFieldName;
    private string outputFieldName;
    private string columnName;
    private string sqlType;
    private bool isPrimaryKey;
    private bool isCollection;
    private string jointBinding;
    private string jointColumn;
    private string jointTable;
    private string nullableValue;
    private bool ignore;
    private string direction;
    private ObjectSqlMapping subQuery = null;
	  /// <summary>
	  /// A new property binding with an identifier.
	  /// </summary>
	  /// <param name="name">Name of the binding</param>
    public ObjectPropertySqlBinding(string name) : base(name) { }
    /// <summary>
    /// The type of data in the database column that is bound to this property.
    /// </summary>
    public string SqlType
    {
      get { return sqlType; }
      set { sqlType = value; }
    }
    /// <summary>
    /// The name of the property
    /// </summary>
    public string PropertyName
    {
      get { return propertyName; }
      set { propertyName = value; }
    }
    /// <summary>
    /// The name of the input parameter
    /// </summary>
    public string InputFieldName
    {
      get 
      {
        if (string.IsNullOrEmpty(inputFieldName))
        {
          return PropertyName;
        }
        return inputFieldName; 
      }
      set 
      { 
        if(!string.IsNullOrEmpty(value))
        {        
          inputFieldName = value; 
        }
      }
    }
    /// <summary>
    /// The name of the output parameter.
    /// </summary>
    public string OutputFieldName
    {
      get 
      {
        if (string.IsNullOrEmpty(outputFieldName))
        {
          return ColumnName;
        }
        return outputFieldName; 
      }
      set 
      { 
        if(!string.IsNullOrEmpty(value))
        {        
          outputFieldName = value; 
        }
      }
    }
    /// <summary>
    /// Marks this as the primary key binding of the enclosing table (<see cref="ObjectSqlMappingTable"/>).
    /// </summary>
    public bool IsPrimaryKey
    {
      get { return isPrimaryKey; }
      set { isPrimaryKey = value; }
    }
    /// <summary>
    /// Name of the column in the enclosing table that refers to this binding.
    /// </summary>
    public string ColumnName
    {
      get { return columnName; }
      set { columnName = value; }
    }
    /// <summary>
    /// Name of the table
    /// </summary>
    public string TableName
    {
      get { return tableName; }
      set { tableName = value; }
    }
    /// <summary>
    /// Referenced mapping (see PropertyBindingData.RefType).
    /// </summary>
    public ObjectSqlMapping SubQuery
    {
      get { return subQuery; }
      set { subQuery = value; }
    }
    /// <summary>
    /// If true, this is a binding to a collection of objects defined by <see cref="SubQuery"/>.
    /// </summary>
    public bool IsCollection
    {
      get { return isCollection; }
      set { isCollection = value; }
    }
    /// <summary>
    /// The name of a referenced binding.
    /// </summary>
    public string JointBinding
    {
      get { return jointBinding; }
      set { jointBinding = value; }
    }
    /// <summary>
    /// Name of a column in the referenced binding.
    /// </summary>
    public string JointColumn
    {
      get { return jointColumn; }
      set { jointColumn = value; }
    }
    /// <summary>
    /// Name of a column in the referenced mapping.
    /// </summary>
    public string JointTable
    {
      get { return jointTable; }
      set { jointTable = value; }
    }
    /// <summary>
    /// String representation of a nullable value for the column in this binding.
    /// </summary>
    public string NullableValue
    {
      get { return nullableValue; } set { nullableValue = value; }
    }
    /// <summary>
    /// Whether to ignore this binding when performing the mapping.
    /// </summary>
    public bool Ignore
    {
      get { return ignore; }
      set { ignore = value; }
    }
    /// <summary>
    /// In the case of store procedures this is either IN or OUT
    /// </summary>
    public string Direction
    {
      get { return direction; }
      set { direction = value; }
    }

    #region ICloneable Members
    /// <summary>
    /// Implementation of the <see cref="ICloneable.Clone"/> method.
    /// </summary>
    /// <returns></returns>
    public object Clone()
    {
      ObjectPropertySqlBinding clone = new ObjectPropertySqlBinding(this.Name);
      clone.TableName = this.TableName;
      clone.PropertyName = this.PropertyName;
      clone.InputFieldName = this.InputFieldName;
      clone.OutputFieldName = this.OutputFieldName;
      clone.ColumnName = this.ColumnName;
      clone.SqlType = this.SqlType;
      clone.IsPrimaryKey = this.IsPrimaryKey;
      clone.IsCollection = this.IsCollection;
      clone.TableName = this.TableName;
      clone.TableName = this.TableName;
      clone.JointColumn = this.JointColumn;
      clone.JointBinding = this.JointBinding;
      clone.JointTable = this.JointTable;
      clone.NullableValue = this.NullableValue;
      clone.Direction = this.Direction;
      if (this.SubQuery != null)
      {
        clone.SubQuery = (ObjectSqlMapping)this.SubQuery.Clone();
      }
      return clone;
    }

    #endregion
  }
}
